package data;

import helpers.IdUniqueHelper;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.cache.Cache;
import javax.cache.CacheException;
import javax.cache.CacheManager;
import models.CountModel;
import models.DealModel;

import admin.data.DealData;

import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyOpts;
import com.googlecode.objectify.ObjectifyService;
import com.googlecode.objectify.Query;

public class CountData {
	private Objectify ofy;

	private Cache cache = null;

	private String prefix = "countData";

	private int limit = 20;

	private int page = 1;

	public int getLimit() {
		return limit;
	}

	public void setLimit(int limit) {
		this.limit = limit;
	}

	public int getPage() {
		return page;
	}

	public void setPage(int page) {
		this.page = page;
	}

	public CountData() {
		try {
			ObjectifyService.register(CountModel.class);
		} catch (Exception e) {
			// e.printStackTrace();
		}

		try {
			cache = CacheManager.getInstance().getCacheFactory()
					.createCache(Collections.emptyMap());
		} catch (CacheException e) {
			// e.printStackTrace();
		}

		ObjectifyOpts opts = new ObjectifyOpts().setSessionCache(true);
		ofy = ObjectifyService.begin(opts);
	}

	@SuppressWarnings("unchecked")
	public void insert(CountModel count) {
		if (cache != null) {
			cache.put(prefix + count.getCategoryId() + count.getCityId(), count);
		}
		ofy.put(count);
	}

	public void delete(CountModel count) {
		if (cache != null
				&& cache.containsKey(prefix + count.getCategoryId()
						+ count.getCityId())) {
			cache.remove(prefix + count.getCategoryId() + count.getCityId());
		}
		ofy.delete(count);
	}

	@SuppressWarnings("unchecked")
	public CountModel getCount(String cateId, String cityId) {
		CountModel countModel = new CountModel();
		if (cache != null && cache.containsKey(prefix + cateId + cityId)) {
			countModel = (CountModel) cache.get(prefix + cateId + cityId);
		} else {
			try {
				countModel = ofy.query(CountModel.class)
						.filter("cityId", cityId).filter("categoryId", cateId)
						.get();
				cache.put(prefix + cateId + cityId, countModel);
			} catch (Exception e) {
				countModel = null;
			}
		}
		return countModel;
	}

	public int getCountByCity(String cityId) {
		List<CountModel> list = new ArrayList<CountModel>();
		int count = 0;
		list = ofy.query(CountModel.class).filter("cityId", cityId).list();
		for (CountModel countModel : list) {
			count += countModel.getCount();
		}
		return count;
	}

	public List<CountModel> list() {
		List<CountModel> list = new ArrayList<CountModel>();
		int start = (page - 1) * limit;
		Query<CountModel> q = ofy.query(CountModel.class).limit(limit)
				.offset(start);
		for (CountModel countModel : q) {
			list.add(countModel);
		}
		return list;
	}

	public void recountAll() {
		page = 1;
		limit = 488;
		while (true) {
			List<CountModel> list = list();
			for (CountModel countModel : list) {
				delete(countModel);
			}
			if (list.size() < limit) {
				break;
			} else {
				page++;
			}
		}

		DealData dealData = new DealData();
		dealData.setPage(1);
		dealData.setLimit(488);
		while (true) {
			dealData.prepareList();
			List<DealModel> list = dealData.getListResult();
			for (DealModel deal : list) {
				if (deal.getStatus() == 2) {
					CountModel countModel = getCount(deal.getCategory(),
							deal.getCity());
					if (countModel != null) {
						countModel.setCount(countModel.getCount() + 1);
					} else {
						countModel = new CountModel();
						countModel.setCountId(IdUniqueHelper.getId());
						countModel.setCategoryId(deal.getCategory());
						countModel.setCityId(deal.getCity());
						countModel.setCount(1);
					}
					insert(countModel);
				}
			}
			if (list.size() < dealData.getLimit()) {
				break;
			} else {
				dealData.setPage(dealData.getPage() + 1);
			}
		}

	}
}
